package com.dg.service.impl;

import com.dg.dao.*;
import com.dg.dto.RoleAclModuleTreeDto;
import com.dg.exception.ParamException;
import com.dg.param.RoleParam;
import com.dg.pojo.*;
import com.dg.service.RoleService;
import com.dg.util.StringUtil;
import com.dg.util.ValidatorUtil;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author mrq
 */
@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private RoleUserMapper roleUserMapper;
    @Autowired
    private AclMapper aclMapper;
    @Autowired
    private AclModuleMapper aclModuleMapper;
    @Autowired
    private RoleAclMapper roleAclMapper;

    @Override
    public List<Role> list(){
        return roleMapper.getAll();
    }

    @Override
    public void save(RoleParam param) {
        ValidatorUtil.validate(param);
        if(checkExist(param.getId(), param.getName())){
            throw new ParamException("角色名已存在");
        }
        Role dept = Role.builder().name(param.getName()).type(param.getType()).status(param.getStatus()).remark(param.getRemark())
                .operator("admin").operateIp("127.0.0.1").operateTime(new Date()).build();
        roleMapper.insertSelective(dept);
    }

    @Override
    public void update(RoleParam param){
        ValidatorUtil.validate(param);
        if (checkExist(param.getId(), param.getName())){
            throw new ParamException("角色名已存在");
        }
        Role dept = Role.builder().id(param.getId()).name(param.getName()).type(param.getType()).status(param.getStatus()).remark(param.getRemark())
                .operator("admin").operateIp("127.0.0.1").operateTime(new Date()).build();
        roleMapper.updateByPrimaryKeySelective(dept);
    }

    @Override
    public void delete(Integer id) {
        if (id == null){
            throw new ParamException("id不能为空");
        }
        if (checkUserExistByDeptId(id)){
            throw new ParamException("角色与用户有关联，无法删除");
        }
        roleMapper.deleteByPrimaryKey(id);
    }

    @Override
    public List<RoleAclModuleTreeDto> roleTree(Integer id) {
        if (id == null){
            throw new ParamException("id不能为空");
        }
        //当前系统所有权限点
        List<Acl> aclAll = aclMapper.getAll();

        //当前角色分配的权限点
        List<Integer> aclIdList = roleAclMapper.getAclListByRoleId(id);

        List<RoleAclModuleTreeDto> roleAclModuleTreeDtoList = Lists.newArrayList();
        for (Acl acl : aclAll){
            RoleAclModuleTreeDto roleAclModuleTreeDto = RoleAclModuleTreeDto.adapter(acl);
            if(aclIdList.contains(acl.getId())){
                roleAclModuleTreeDto.setChecked(true);
            }
            roleAclModuleTreeDtoList.add(roleAclModuleTreeDto);
        }

        //获取所有模块
        List<AclModule> aclModuleList = aclModuleMapper.getAll();
        for (AclModule aclModule : aclModuleList){
            RoleAclModuleTreeDto roleAclModuleTreeDto = RoleAclModuleTreeDto.adapter(aclModule);
            roleAclModuleTreeDtoList.add(roleAclModuleTreeDto);
        }

        List<RoleAclModuleTreeDto> rootList = Lists.newArrayList();
        Multimap<Integer, RoleAclModuleTreeDto> map = ArrayListMultimap.create();
        for (RoleAclModuleTreeDto dto : roleAclModuleTreeDtoList){
            if (dto.getParentId() == 0){
                rootList.add(dto);
            }
            map.put(dto.getParentId(), dto);
        }
        Collections.sort(rootList, comparator);
        return tree(rootList, map);
    }

    @Override
    public void changeAcl(Integer roleId, String ids) {
        if(roleId == null){
            throw new ParamException("roleId不能为空");
        }
        List<RoleAcl> roleAclList = Lists.newArrayList();
        if (StringUtils.isNotBlank(ids)){
            List<Integer> aclIdList = StringUtil.splitToListInt(ids);
            for (Integer aclId : aclIdList){
                RoleAcl roleAcl= RoleAcl.builder().roleId(roleId).aclId(aclId)
                        .operateIp("127.0.0.1").operateTime(new Date()).operator("admin").build();
                roleAclList.add(roleAcl);
            }
        }
        batchRoleAcl(roleId, roleAclList);
    }

    @Override
    public void changeRoleUser(Integer roleId, String ids) {
        if(roleId == null){
            throw new ParamException("roleId不能为空");
        }
        List<RoleUser> roleUserList = Lists.newArrayList();
        if (StringUtils.isNotBlank(ids)){
            List<Integer> userIdList = StringUtil.splitToListInt(ids);
            for (Integer userId : userIdList){
                RoleUser roleUser =RoleUser.builder().roleId(roleId).userId(userId)
                        .operateIp("127.0.0.1").operateTime(new Date()).operator("admin").build();
                roleUserList.add(roleUser);
            }
        }
        batchRoleUser(roleId,roleUserList);
    }

    @Transactional(rollbackFor = Exception.class)
    private void batchRoleUser(Integer roleId, List<RoleUser> roleUserList) {
        roleUserMapper.batchDeleteByRoleId(roleId);
        if (CollectionUtils.isNotEmpty(roleUserList)){
            roleUserMapper.batchInsert(roleUserList);
        }
    }

    /**
     * 批量操作
     * @param roleId
     * @param roleAclList
     */
    @Transactional(rollbackFor = Exception.class)
    private void batchRoleAcl(Integer roleId, List<RoleAcl> roleAclList) {
        roleAclMapper.batchDelete(roleId);
        if(CollectionUtils.isNotEmpty(roleAclList)){
            roleAclMapper.batchInsert(roleAclList);
        }
    }

    private List<RoleAclModuleTreeDto> tree(List<RoleAclModuleTreeDto> rootList, Multimap<Integer,RoleAclModuleTreeDto> map) {
        for (RoleAclModuleTreeDto dto : rootList){
            //查出子节点
            List<RoleAclModuleTreeDto> list =( List<RoleAclModuleTreeDto>) map.get(dto.getId());
            //排序处理
            Collections.sort(list, comparator);
            dto.setChildren(list);
            //递归
            tree(list, map);
        }
        return rootList;
    }


    private boolean checkExist(Integer id, String name) {
        return roleMapper.findByName(id,name) > 0;
    }

    private boolean checkUserExistByDeptId(Integer id) {
        return roleUserMapper.countByRoleId(id) > 0;
    }

    private Comparator<RoleAclModuleTreeDto> comparator = new Comparator<RoleAclModuleTreeDto>() {
        @Override
        public int compare(RoleAclModuleTreeDto o1, RoleAclModuleTreeDto o2) {
            return o1.getSeq() - o2.getSeq();
        }
    };

}
